#include "ecs_components.hpp"


namespace njm
{
    // 矩阵转换
    // 先scale，再rotate，最后translate
    // 旋转顺序：先绕Z轴旋转，再绕X轴旋转，最后绕Y轴旋转
    // glm::mat4 mat4() {
    //     auto transform = glm::translate(glm::mat4(1.f), position);
    //     transform = glm::rotate(transform, rotation.y, {0.f, 1.f, 0.f});
    //     transform = glm::rotate(transform, rotation.x, {1.f, 0.f, 0.f});
    //     transform = glm::rotate(transform, rotation.z, {0.f, 0.f, 1.f});
    //     transform = glm::scale(transform, scale);
    //     return transform;
    // }
    glm::mat4 Transform::mat4()
    {
        const float c3 = glm::cos(rotation.z);
        const float s3 = glm::sin(rotation.z);
        const float c2 = glm::cos(rotation.x);
        const float s2 = glm::sin(rotation.x);
        const float c1 = glm::cos(rotation.y);
        const float s1 = glm::sin(rotation.y);
        return glm::mat4{
            {
                scale.x * (c1 * c3 + s1 * s2 * s3),
                scale.x * (c2 * s3),
                scale.x * (c1 * s2 * s3 - c3 * s1),
                0.0f,
            },
            {
                scale.y * (c3 * s1 * s2 - c1 * s3),
                scale.y * (c2 * c3),
                scale.y * (c1 * c3 * s2 + s1 * s3),
                0.0f,
            },
            {
                scale.z * (c2 * s1),
                scale.z * (-s2),
                scale.z * (c1 * c2),
                0.0f,
            },
            {position.x, position.y, position.z, 1.0f}};
    }
    glm::mat3 Transform::normalMatrix()
    {
        const float c3 = glm::cos(rotation.z);
        const float s3 = glm::sin(rotation.z);
        const float c2 = glm::cos(rotation.x);
        const float s2 = glm::sin(rotation.x);
        const float c1 = glm::cos(rotation.y);
        const float s1 = glm::sin(rotation.y);
        const glm::vec3 inverseScale = 1.0f / scale;
        return glm::mat3{
            {
                inverseScale.x * (c2 * s3),
                inverseScale.x * (c1 * s2 * s3 - c3 * s1),
                inverseScale.x * (c1 * c3 + s1 * s2 * s3),
            },
            {
                inverseScale.y * (c3 * s1 * s2 - c1 * s3),
                inverseScale.y * (c2 * c3),
                inverseScale.y * (c1 * c3 * s2 + s1 * s3),
            },
            {
                inverseScale.z * (c2 * s1),
                inverseScale.z * (-s2),
                inverseScale.z * (c1 * c2),
            },
        };
    }
}
